#include <stdio.h>
#include "graph.h"
#include "symbols.h"
#include "lex-tools.h"
#include "parser-tools.h"
#include "lexer.h"
#include "limits.h"
#include <stdlib.h>

void algopt_parser_program();
void algopt_parser_statement();
void algopt_parser_numberstat();
void algopt_parser_number();
void algopt_parser_numberof();
void algopt_parser_numberofvertices();
void algopt_parser_numberofedges();
void algopt_parser_capacity();
void algopt_parser_time();
void algopt_parser_listofedges();
void algopt_parser_depot();
void algopt_parser_edgelist();
void algopt_parser_edgedef();

Pgraph graph;
int* N;


Pgraph parseGraph(FILE* file, int* _N){
	yyin=file;
	N=_N;
	next();
	algopt_parser_program();
	return graph;
}

void algopt_parser_program(){
	while (lookahead!=ENDOFFILE){
		algopt_parser_statement();
	}
}

void algopt_parser_statement(){
	switch (lookahead){
		case _NUMBER: {
			algopt_parser_numberstat();
			break;
		}
		case _CAPACITY: {
			algopt_parser_capacity();
			break;
		}
		case _TIME: {
			algopt_parser_time();
			break;
		}
		case _LIST: {
			algopt_parser_listofedges();
			break;
		}
		case _DEPOT: {
			algopt_parser_depot();
			break;
		}
		default: {
			fprintf(stderr,"errore in statement \"%s\"\n",yytext);
			break;
		}
	}
}

void algopt_parser_numberstat(){
	match(_NUMBER);
	switch (lookahead){
		case COLON: {
			algopt_parser_number();
			break;
		}
		case _OF: {
			algopt_parser_numberof();
			break;
		}
		default: {
			fprintf(stderr,"errore in numberstat\n");
			break;
		}
	}
}

void algopt_parser_number(){
	match(COLON);
	LexVal n=match(_FILENAMECONST);
	//printf("\"%s\"\n",n.sval);
}

void algopt_parser_numberof(){
	match(_OF);
	switch (lookahead){
		case _VERTICES: {
			algopt_parser_numberofvertices();
			break;
		}
		case _EDGES: {
			algopt_parser_numberofedges();
			break;
		}
		default: {
			fprintf(stderr,"errore in numberof\n");
			break;
		}
	}
}

void algopt_parser_numberofvertices(){
	match(_VERTICES);
	match(COLON);
	LexVal n=match(_INTEGERCONST);
	//get del numero di vertici V
	*N=n.ival;
	graph=initCompleteGraph(N,0,0,0,*initEdgeGraph(INFINITE,0,0));
}

void algopt_parser_numberofedges(){
	match(_EDGES);
	match(COLON);
	match(_INTEGERCONST);
	//get numero di archi: la matrice Graph non ne ha bisogno
	//graph.archiprofittevoli=*(int*)tokenRead.value;
}

void algopt_parser_capacity(){
	match(_CAPACITY);
	match(COLON);
	LexVal n=match(_INTEGERCONST);
	//get capacita' Q
	graph->Q=n.ival;
}

void algopt_parser_time(){
	match(_TIME);
	match(_LIMIT);
	match(COLON);
	LexVal n=match(_INTEGERCONST);
	//get T
	graph->T=n.ival;
}

void algopt_parser_listofedges(){
	match(_LIST);
	match(_OF);
	match(_EDGES);
	match(COLON);
	algopt_parser_edgelist();
}

void algopt_parser_depot(){
	match(_DEPOT);
	match(COLON);
	LexVal n=match(_INTEGERCONST);
	//prendi il numero del deposito
	graph->depot=n.ival-1;
}

void algopt_parser_edgelist(){
	while (lookahead==OPENPARENTHESIS){
		algopt_parser_edgedef();
	}
}

void algopt_parser_edgedef(){
	LexVal n;
	EdgeID id;

	match(OPENPARENTHESIS);
	n=match(_INTEGERCONST);
	id.i=n.ival-1;
	match(COMMA);
	n=match(_INTEGERCONST);
	id.j=n.ival-1;
	match(CLOSEPARENTHESIS);
	match(_COST);
	n=match(_INTEGERCONST);

	int cost=n.ival;
	match(_DEMAND);
	n=match(_INTEGERCONST);
	int demand=n.ival;

	match(_PROFIT);
	n=match(_FLOATCONST);
	float profit=n.fval;

	validateEdgeID(&id);
	graph->am[id.i][id.j].d=demand;
	graph->am[id.i][id.j].t=cost;
	graph->am[id.i][id.j].p=profit;

	graph->E++;
}
